class RenderSystem extends System {
	constructor(world) {
		super(world);

        this._backgroundColor = '#336666';

		const canvas = document.getElementById('scene');
		canvas.width = config.width;
		canvas.height = config.height;

		this._canvas = canvas;
		this._context = canvas.getContext('2d');

        window.onresize = () => this.resetCanvas();
        this.resetCanvas();
	}

    resetCanvas() {
        const canvas = this._canvas;
        const bodyWidth = document.body.clientWidth;
        const bodyHeight = document.body.clientHeight;
        canvas.style.left = `${Math.max(0, (bodyWidth - config.width) / 2)}px`;
        canvas.style.top = `${Math.max(0, (bodyHeight - config.height) / 2)}px`;
    }

	render(command) {
		const context = this._context;
		context.save();
        command(context);
		context.restore();
	}
	
	execute() {
		this.clear();
        this.renderBalls();
        this.renderPlayer();
        this.renderScores();
	}

	renderBalls() {
        for (const entity of this.getWorld().getEntities()) {
            const ballComponent = entity.getComponent(BallComponent);
            const positionComponent = entity.getComponent(PositionComponent);
            if (ballComponent && positionComponent) {
                this.render(context => {
                    const {color} = ballComponent;
                	const {x, y} = positionComponent;
                    context.fillStyle = color;
                    context.beginPath();
                    context.arc(x, y, config.ballRadius, 0, 360, false);
                    context.closePath();
                    context.fill();
                });
            }
        }
	}

	renderPlayer() {
        for (const entity of this.getWorld().getEntities()) {
            const ballComponent = entity.getComponent(BallComponent);
            const positionComponent = entity.getComponent(PositionComponent);
            const playerControllerComponent = entity.getComponent(PlayerControllerComponent);
            if (ballComponent && positionComponent && playerControllerComponent) {
                this.render(context => {
                    const {color} = ballComponent;
                    const {x, y} = positionComponent;
                    context.fillStyle = color;
                    context.beginPath();
                    context.arc(x, y, config.ballRadius, 0, 360, false);
                    context.closePath();
                    context.fill();

                    context.font = `bold 32px Arial`;
                    context.fillStyle = '#dfdfdf';
                    context.textAlign = 'center';
                    context.textBaseline = 'middle';
                    context.fillText('P', x, y);
                });
            }
        }
    }

    renderScores() {
	    for (const entity of this.getWorld().getEntities()) {
            const scoreComponent = entity.getComponent(ScoreComponent);
            const positionComponent = entity.getComponent(PositionComponent);
            if (scoreComponent && positionComponent) {
                this.render(context => {
                    const {color, progress} = scoreComponent;
                    const {x, y} = positionComponent;
                    context.font = `bold ${26 * progress}px Arial`;
                    context.fillStyle = color;
                    context.textAlign = 'center';
                    context.textBaseline = 'middle';
                    context.fillText('+1', x, y);
                });
            }
        }
    }
	
	clear() {
        this.render(context => {
            context.fillStyle = this._backgroundColor;
            context.fillRect(0, 0, config.width, config.height);
        });
	}
}